home *** CD-ROM | disk | FTP | other *** search
-
- ********************************************************************
- ************************ FSTACK by Rex Kerr ************************
- ************************ Copyright (C) 1989 ************************
- ********************************************************************
-
- This is a Turbo Pascal unit written in assembly language that lets
- you create stacks that can be used like the CPU's main stack. You
- can have either byte or word stacks, and you can switch as often as
- you like. You can only have one active byte or word stack at one
- time, though.
-
- There are 7 routines for word stacks, and seven more for byte stacks.
-
- ***
-
- InitWStack(var buf; len : word);
-
- This initializes the word stack. Len is the length of buf. If you
- are passing a pointer to something, make sure you pass the something
- instead of the pointer:
-
- var st : ^string;
- begin
- new(st);
- initwstack(st^,sizeof(st^)); { Right. }
- initwstack(st,sizeof(st)); { Now your buffer is the pointer!
- You only have 4 bytes! }
- initwstack(st,sizeof(st^)); { This is dangerous! If you do
- too much pushing, you'll run
- past the 4 byte pointer ... }
- initwstack(st^,sizeof(st)); { This is wasteful! You have 256
- bytes available, but have said
- you only have 4 }
- dispose(st);
- end.
-
- ***
-
- InitBStack(var buf; len : word);
-
- This is exactly the same as InitWStack, except it initializes the
- byte stack.
-
- ***
-
- ClearWStack;
-
- This just clears the word stack.
-
- ***
-
- ClearBStack;
-
- This clears the byte stack.
-
- ***
-
- WStackEmpty : boolean;
-
- This returns true if the word stack is empty.
-
- ***
-
- BStackEmpty : boolean;
-
- This returns true if the byte stack is empty.
-
- ***
-
- PushW(w : word);
-
- This pushes one word onto the word stack (if it isn't full).
-
- ***
-
- PushB(b : byte);
-
- This pushes one byte onto the byte stack (if it isn't full).
-
- ***
-
- PopW : word;
-
- This pops one word from the word stack. It is a function for
- flexibility and speed.
-
- ***
-
- PopB : byte;
-
- This pops one byte from the byte stack.
-
- ***
-
- WStackSize : word;
-
- This returns the current number of entries in the word stack. To
- find the maximum word size do:
-
- Max_Size := sizeof(buf) shr 1;
-
- And to find the number of free spaces (assuming you have found
- Max_Size) you do:
-
- free_spaces := Max_Size - WStackSize;
-
- ***
-
- BStackSize : word;
-
- BStackSize returns the number of entries in the byte stack.
- Max_Size for the byte stack is the same thing as sizeof(buf).
-
- ***
-
- SetWStack(size : word);
-
- You use this for swapping stacks. Like this:
-
- var bufa,bufb : array[1..100] of byte;
- sizea : word
- begin
- initwstack(bufa,sizeof(bufa)); { Initialize the stack }
- ( . . . ) { Do some stuff to it }
- sizea := wstacksize; { Get the size of the stack }
- initwstack(bufb,sizeof(bufb)); { Re-initialize stack #2 }
- ( . . . ) { Do whatever with stack #2 }
- initwstack(bufa,sizeof(bufa)); { Back to stack #1, but it
- thinks it is empty }
- setwstack(sizea); { Now we're back to the first
- stack the way it was }
- end.
-
- Please note that only pushes actually change the values in the
- stack. The others just set different hidden variables or read
- from the stack. SetWStack just sets the length of the stack to
- what size you specify; it in no way changes the contents of the
- stack. ClearWStack just calls SetWStack(0).
-
- ***
-
- SetBStack(size : word);
-
- This does for the byte stack what SetWStack does for the word stack.
-
- ***
-
- One useful place for this is in a non-recursive form of QuickSort.
-
- For short stacks, FSTACK is much better than a linked list stack.
- Here are the reasons why:
-
- 1) It is much faster (3 or 4 times, I think)
- 2) It has no overhead per item
- 3) You can access the stack as an array
-
- You also can have just the amount of space you want like this:
-
- program Get_Just_Enough;
- uses fstack;
- type stackarry : array[1..100] of byte;
- var b : ^stackarry;
- len : word;
- begin
- len := 14; { Or however much you need }
- getmem(b,len); { Get the memory }
- initstack(b^,sizeof(b^)); { Initialize the stack }
- ( . . . ) { Use the stack }
- freemem(b,len); { Free the memory used }
- end.
-
- It isn't a good idea to reallocate b while you are using the stack,
- in case the place where b is stored is moved. If it is moved,
- you can fix that with the Qmove procedure in FMISC. The regular
- move also works, but Qmove is twice as fast. Like this:
-
- uses fmisc,fstack;
- type stackarry := array[1..100] of word;
- { If range checking is off, the 1..100 may be any size. If it's on,
- stackarry must be at least as large as the largest getmem (to avoid a
- range check error) }
- var len,size : word; { len is to store the getmem value,
- size is to store wstacksize }
- b,temptr : ^stackarry; { You'll need the extra pointer }
- begin
- len := 14; { Set getmem length }
- getmem(b,len); { Get the memory }
- initwstack(b^,len); { Initialize the stack }
- ( . . . ) { Use the stack & find it is too small }
- temptr := b; { Save the address of the buffer }
- freemem(b,len); { Free the buffer's memory }
- len := 28; { Set the new length }
- getmem(b,len); { Get the memory }
- size := wstacksize; { Get the stack size }
- if temptr <> b then { If temptr <> b, the b has been moved }
- begin
- qmove(temptr,b,size); { Move the stack values to the
- end; new location }
- initwstack(b^,len); { Re-initialize the stack to the new
- maximum length (and maybe location) }
- setwstack(size); { Set the stack to use the old pushed
- values }
- ( . . . ) { Do whatever you want }
- freemem(b,len); { Free the allocated memory }
- end. { We're done. }
-
- All of the byte stack things work just like the word stack things,
- except you push and pop bytes. You will probably have to use
- value typecasting (for things like characters and integers).
- And also you'll have to split things like longints up. When you
- are doing that, remember that if you push the high part first and
- then the low part, you should pop the low part and then the high
- part to get it back the same way.
-